﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace EyeballMuscle
{
    public class Eyeball
    {
        VisionReceptor visionReceptor = new VisionReceptor(5);
        InterestingRegion interestingRegion = new InterestingRegion(11);
        MotorConnetion motorConnetion = new MotorConnetion(11);

        Point pointInterest = Point.Empty;
        public Eyeball()
        {
        }

        public void Input()
        {
            //更新刺激
            visionReceptor.Update();
            //检测特征点
            //如果未检测到任何特征，则重新获取数据
            //如果检测到相同特征，计算特征点是否增强
            //如果特征增强，则增加上一次运动连接权值
            //如果特征减弱，则减弱上一次运动连接权值
            Point pointLast = interestingRegion.FeaturePoint;
            //重新获取特征兴趣点
            pointInterest = interestingRegion.GetMaxInterest(visionReceptor.Bounds, visionReceptor.Values);
            if (pointInterest!=Point.Empty &&  interestingRegion.FeatureMatch)
            {//特征匹配
                if (interestingRegion.FeatureIncrease)
                {//特征增强
                    if (pointLast != Point.Empty)
                    {
                        if (motorConnetion[pointLast.X, pointLast.Y, 0] > 0)
                            motorConnetion[pointLast.X, pointLast.Y, 0]++;
                        else if(motorConnetion[pointLast.X, pointLast.Y, 0] < 0)
                            motorConnetion[pointLast.X, pointLast.Y, 0]--;
                    }
                }
                else
                {//特征减弱
                }
            }
            //获取运动点的运动方向
            int x = motorConnetion[pointInterest.X, pointInterest.Y, 0];
            int y = motorConnetion[pointInterest.X, pointInterest.Y, 1];

            visionReceptor.Bounds.Offset(x, y);



        }
    }

    public class MotorConnetion
    {
        short[][,] connections = new short[2][,];
        public MotorConnetion(int length)
        {
            for (int i = 0; i < 2; i++)
            {
                connections[i] = new short[length, length];
                Random r = new Random();
                for (int y = 0; y < length; y++)
                {
                    for (int x = 0; x < length; x++)
                    {
                        //随机产生连接强度
                        connections[i][x, y] = (short)r.Next(-2,3);
                    }
                }
            }
        }
        public short this[int x, int y, int d]
        {
            get { return connections[d][x, y]; }
            set { connections[d][x, y] = value; }
        }
    }

    public class MotorNeuron
    {
        public MotorNeuron()
        {
        }
    }

    public class VisionReceptor
    {
        Rectangle bounds;
        public Rectangle Bounds { get { return bounds; } }
        public byte[,] Values { get; private set; }
        public VisionReceptor(int length)
        {
            this.bounds = new Rectangle(0, 0, length, length);
            Values = new byte[length, length];
        }

        public void Update()
        {

        }
    }

    public class InterestingRegion
    {
        Rectangle bounds;
        public Rectangle Bounds { get { return bounds; } }
        bool match = false; //特征是否匹配
        bool increase = false;//特征兴趣是否增加
        Point pointLast = Point.Empty;
        public bool FeatureMatch { get { return match; } }
        public bool FeatureIncrease { get { return increase; } }
        public Point FeaturePoint { get { return pointLast; } }
        byte feature = 0;//特征值
        byte value = 0;//兴趣值
        byte[,] values;//区域兴趣值


        public InterestingRegion(int length)
        {
            bounds = new Rectangle(0, 0, length, length);
            Point center = new Point((length - 1) / 2, (length - 1) / 2);
            values = new byte[length, length];
            for (int y = 0; y <= center.Y; y++)
            {
                for (int x = 0; x <= center.X; x++)
                {
                    values[x, y] =
                    values[length - x - 1, y] =
                    values[x, length - y - 1] =
                    values[length - x - 1, length - y - 1] =
                        (byte)(Math.Min(x, y) + 1);
                }
            }
        }

        public byte this[int x, int y]
        {
            get { return values[x, y]; }
            set { values[x, y] = value; }
        }

        public Point GetMaxInterest(Rectangle bounds, byte[,] datas)
        {
            Point maxPoint = Point.Empty;
            int max = 0;
            byte maxfeature = 0;
            byte maxValue = 0;
            for (int y = bounds.Top; y < bounds.Bottom; y++)
            {
                for (int x = bounds.Left; x < bounds.Right; x++)
                {
                    if (!this.bounds.Contains(x, y)) continue;

                    int val = this.values[x - bounds.Left, y - bounds.Top] * datas[x, y];
                    if (val > max)
                    {
                        max = val;
                        maxPoint.X = x;
                        maxPoint.Y = y;
                        maxfeature = datas[x, y];
                        maxValue = this.values[x - bounds.Left, y - bounds.Top];
                    }
                }
            }

            if (maxPoint != Point.Empty && this.feature == maxfeature)
            {
                this.match = true;

                if (this.value < maxValue)
                {
                    this.increase = true;
                }
                else
                {
                    this.increase = false;
                }

                this.value = maxValue;
            }
            else
            {
                this.feature = maxfeature;

                this.match = false;
            }

            this.pointLast = maxPoint;

            return maxPoint;
        }

    }
}
